import CryptoJS from "crypto-js"
import moment from "moment"
import axios from "axios"

export const appId = "14yfls6j"
const appSecret = "cf2decc52b37426d8ec1920c48cc1cb2"

export function createTimestamp() {
  return moment().utc().format("YYYY-MM-DDTHH:mm:ss[Z]")
}

// 生成随机数
export function generateNonce() {
  return Math.floor(Math.random() * 1000000000).toString()
}

function percentEncode(str: string) {
  // 对参数进行URL编码
  return encodeURIComponent(str)
    .replace(/%20/g, "+")
    .replace(/~/g, "%7E")
    .replace(/!/g, "%21")
    .replace(/\*/g, "%2A")
    .replace(/'/g, "%27")
}

// 构造规范化的请求字符串
export function canonicalizeQueryString(params: any) {
  const sortedParams = Object.keys(params).sort()
  const canonicalizedParams = sortedParams.map((key) => {
    return `${percentEncode(key)}=${percentEncode(params[key])}`
  })
  return canonicalizedParams.join("&")
}

// 构造待签名的字符串
function createSignatureString(httpMethod: string, servletPath: string, canonicalizedQueryString: string) {
  return `${httpMethod}\n${percentEncode(servletPath)}\n${canonicalizedQueryString}`
}

function signStringToSign(signatureString: string, appSecret: string) {
  // console.log("signString打印", signatureString)
  const key = "BC_SIGNATURE&" + appSecret
  //错误写法
  // const hmac = CryptoJS.HmacSHA1(signatureString, CryptoJS.enc.Utf8.parse(key))
  // return CryptoJS.enc.Base64.stringify(hmac)

  const hmac = CryptoJS.HmacSHA1(signatureString, key) // 使用 "HmacSHA1"
  const signature = hmac.toString(CryptoJS.enc.Hex) // 返回十六进制格式的 HMAC
  return signature

  // 原生crypto加密方法
  // const hmac = crypto.createHmac('sha1', secretKey)  // 使用 "sha1" 而非 "HmacSHA1"
  // console.log('sign签名方法',data)
  // hmac.update(data, ENCODING)
  // return hmac.digest("hex")
}

// 构造签名
export function createSignature(httpMethod: string, servletPath: string, params: any) {
  // 构造规范化的请求字符串
  const canonicalizedQueryString = canonicalizeQueryString(params)
  const shai256QueryString = CryptoJS.SHA256(canonicalizedQueryString).toString(CryptoJS.enc.Hex)
  console.log("shai256QueryString", canonicalizedQueryString, shai256QueryString)
  const signatureString = createSignatureString(httpMethod.toUpperCase(), servletPath, shai256QueryString)
  const signature = signStringToSign(signatureString, appSecret)
  return signature
}
export function toBase64(obj: any) {
  // 将对象转换为 JSON 字符串
  const jsonString = JSON.stringify(obj)

  // 使用 crypto-js 对 JSON 字符串进行 Base64 编码
  const base64String = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(jsonString))
  return base64String
}

export function generateUUID() {
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
    const r = (Math.random() * 16) | 0
    const v = c === "x" ? r : (r & 0x3) | 0x8
    return v.toString(16)
  })
}

// ----------------------------------------------------------
// 签名使用:文字转语音，语音转文字
export function textToAudio(data: { text: string }) {
  const httpMethod = "POST"
  const servletPath = "/lingxiyun/api/tts/v1"
  let urlParams: any = {
    AppId: appId,
    Timestamp: createTimestamp(),
    SignatureMethod: "HmacSHA1",
    SignatureVersion: "V1.0",
    SignatureNonce: generateNonce()
  }
  urlParams = { ...urlParams, Signature: createSignature(httpMethod, servletPath, urlParams) }
  const canonicalizedQueryString = canonicalizeQueryString(urlParams)
  const sessionParam = toBase64({ audio_coding: "mp3", native_voice_name: "sc0" })
  // console.log(urlParams, data, canonicalizedQueryString, sessionParam)
  // return request.post({
  //   url: servletPath + "?" + canonicalizedQueryString,
  //   headers: {
  //     "Content-Type": "application/json",
  //     sid: generateUUID(),
  //     sessionParam: sessionParam
  //   },
  //   data
  // })
  // const requestUrl = servletPath + "?" + canonicalizedQueryString
  const requestUrl = "https://hippo.migu.cn" + servletPath + "?" + canonicalizedQueryString
  return new Promise((r) => {
    axios({
      method: "post",
      url: requestUrl,
      responseType: "arraybuffer", // 重要：设置响应类型为 'blob'
      data,
      headers: {
        "Content-Type": "application/json",
        sid: generateUUID(),
        sessionParam: sessionParam
      }
    }).then((res: any) => {
      r(res.data)
    })
  })
}

export function audioToText(data: any, sid: any, endFlag: any, index: number) {
  console.log("发送语音时间", new Date())
  const httpMethod = "POST"
  const servletPath = "/lingxiyun/api/iat/v1"
  // 用于1分钟内的即时语音转文字，适用于短音频的文字转写的场景。
  let urlParams: any = {
    AppId: appId,
    Timestamp: createTimestamp(),
    SignatureMethod: "HmacSHA1",
    SignatureVersion: "V1.0",
    SignatureNonce: generateNonce()
  }
  urlParams = { ...urlParams, Signature: createSignature(httpMethod, servletPath, urlParams) }
  const canonicalizedQueryString = canonicalizeQueryString(urlParams)
  const sessionParam = toBase64({ rate: "16k" })
  const requestUrl = servletPath + "?" + canonicalizedQueryString
  return new Promise((r) => {
    axios({
      method: "post",
      url: requestUrl,
      data,
      headers: {
        "Content-Type": "application/octet-stream",
        sid,
        sessionParam: sessionParam,
        endFlag,
        number: index
      }
    }).then((res: any) => {
      r(res.data)
    })
  })
}

// 语音转文字，语音数据分片发送
export const sendFile = (blob: any, sliceSize: any) => {
  let isEnd = false
  const sid = generateUUID()
  let resstext = ''
  if (!blob) {
    return
  } else {
    const sliceNum = Math.ceil(blob.size / sliceSize)
    const fun: any = async () => {
      for (let i = 0; i < sliceNum; i++) {
        const start = i * sliceSize
        const end = Math.min(start + sliceSize, blob.size)
        const chunk = blob.slice(start, end) // 获取切片
        const isLastChunk = i === sliceNum - 1
        await new Promise((r) => {
          audioToText(chunk, sid, isLastChunk ? "1" : "0", i + 1).then((res: any) => {
            console.log("语音转文字", res, isLastChunk ? "1" : "0", i + 1)
            for (const item of res.body) {
              console.log(item)
              if (item?.ansStr) {
                resstext = resstext + JSON.parse(item.ansStr).ws_s
              }
              if (item.endFlag) {
                isEnd = true //检查是否结束发送
                console.log('获取识别后的文字', resstext);

                break
              }
            }
            r(res)
          })
        })
      }
    }
    fun()
  }
}

// webscoket设置分片
// export const sendFile = (blob: Blob, sliceSize: number) => {
//   const sid = generateUUID();
//   let resstext = '';

//   if (!blob) return;

//   const sliceNum = Math.ceil(blob.size / sliceSize);
//   const socket = new WebSocket('wss://example.com/socket'); // 替换为实际的 WebSocket 地址

//   socket.onopen = () => {
//     console.log('WebSocket connection established');

//     const uploadChunks = async () => {
//       for (let i = 0; i < sliceNum; i++) {
//         const start = i * sliceSize;
//         const end = Math.min(start + sliceSize, blob.size);
//         const chunk = blob.slice(start, end); // 获取切片
//         const isLastChunk = i === sliceNum - 1;

//         const message = {
//           sid,
//           chunk: chunk,
//           isLastChunk: isLastChunk,
//           chunkIndex: i + 1
//         };

//         socket.send(JSON.stringify(message));
//       }
//     };

//     uploadChunks();
//   };

//   socket.onmessage = (event) => {
//     const response = JSON.parse(event.data);
//     console.log('Received message from server:', response);

//     if (response.body) {
//       for (const item of response.body) {
//         if (item?.ansStr) {
//           resstext += JSON.parse(item.ansStr).ws_s;
//         }
//         if (item.endFlag) {
//           console.log('获取识别后的文字', resstext);
//           socket.close();
//           break;
//         }
//       }
//     }
//   };

//   socket.onerror = (error) => {
//     console.error('WebSocket error:', error);
//   };

//   socket.onclose = () => {
//     console.log('WebSocket connection closed');
//   };
// };

// export function test() {
//   console.log("发送时间", new Date())
//   request
//     .post({
//       url: "/client/user/queryNormalCollectionList",
//       data: {
//         pageNo: 1,
//         pageSize: 10,
//         queryType: 1
//       }
//     })
//     .then((r) => {
//       console.log("请求成功", new Date())
//       console.log("普通藏品", r)
//     })
// }
// test()


